#include "DArray.h"
#include <memory.h>
#include <limits>

#ifndef NULL
#define NULL (0L)
#endif

#ifndef SAFE_DELETE
#define SAFE_DELETE(d)	{ if(d) { delete d; d = NULL; } }
#endif

template<typename Type>
DArray<Type>::DArray(void)
{
	m_ArrayItems = NULL;
	m_ArraySize = 0;
	m_ArrayMaxSize = 0;
}

template<typename Type>
DArray<Type>::~DArray(void)
{
	SAFE_DELETE(m_ArrayItems);
	m_ArraySize = 0;
	m_ArrayMaxSize = 0;
}

template<typename Type>
DArray<Type>::DArray(const DArray& _array)
{
	this = _array;
}

template<typename Type>
DArray<Type>& DArray<Type>::operator =(const DArray<Type>& _array)
{
	if( _array.m_ArrayMaxSize > m_ArrayMaxSize ) {
		m_ArraySize = _array.m_ArraySize;

		SAFE_DELETE(m_ArrayItems);

		m_ArrayItems = new Type[_array.m_ArrayMaxSize];
	}

	m_ArrayMaxSize = _array.m_ArrayMaxSize;
	memcpy((char*)&m_ArrayItems, (char*)&_array, sizeof(Type)*_array.m_ArraySize);
}

template<typename Type>
Type& DArray<Type>::operator[](_uint32 _index)
{
	if( m_ArrayItems )
	{
		return m_ArrayItems[_index];
	}

	return NULL;
}

template<typename Type>
void DArray<Type>::push_back(const Type& _item)
{
	// Max has been reach
	if( m_ArraySize == m_ArrayMaxSize ) {
		
	}
	// Add the new item and adjust the current size;
	m_ArrayItems[m_ArraySize] = _item;
	m_ArraySize++;
}

template<typename Type>
void DArray<Type>::resize(_uint32 _size)
{
	if( _size > m_ArrayMaxSize ) {
		// Check for an overflow
		if( UINT_MAX - m_ArrayMaxSize < m_ArrayMaxSize )
			m_ArrayMaxSize = UINT_MAX;
		// If there hasn't been any items, set it to 2
		// Else double in size
		else if( m_ArrayMaxSize == 0 )
			m_ArrayMaxSize = 2;
		else
			m_ArrayMaxSize *= 2;
		// Hold onto a pointer to the old array of items
		Type* oldArray = m_ArrayItems;
		// Create a new array of items
		m_ArrayItems = new Type[m_ArrayMaxSize];
		// Copy the old items into the array of new items
		memcpy((char*)&m_ArrayItems, (char*)&oldArray, sizeof(Type)*m_ArraySize);
		// Delete the old array
		SAFE_DELETE(oldArray);
	}
}

template<typename Type>
_uint32	DArray<Type>::size(void)
{
	return m_ArraySize;
}

template<typename Type>
void DArray<Type>::clear(void)
{
	SAFE_DELETE(m_ArrayItems);
	m_ArraySize = 0;
	m_ArrayMaxSize = 0;
}